package com.xxx.article.service.impl;

import com.xxx.article.domain.Comment;
import com.xxx.article.repository.CommentRepository;
import com.xxx.article.service.CommentService;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author blijojo
 * @date 2021/6/14
 */
@Service
public class CommentServiceImpl implements CommentService {

    private final CommentRepository commentRepository;

    private final MongoTemplate mongoTemplate;

    private final RedisTemplate<String, String> redisTemplate;


    public CommentServiceImpl(CommentRepository commentRepository, MongoTemplate mongoTemplate, RedisTemplate<String, String> redisTemplate) {
        this.commentRepository = commentRepository;
        this.mongoTemplate = mongoTemplate;
        this.redisTemplate = redisTemplate;
    }

    @Override
    public List<Comment> findAll() {
        return commentRepository.findAll();
    }

    @Override
    public Comment findById(String id) {
        Optional<Comment> optional = commentRepository.findById(id);
        return optional.orElse(null);
    }

    @Override
    public void save(Comment comment) {
        comment.setThumbUp(0);
        comment.setPublishDate(new Date());
        commentRepository.save(comment);
    }

    @Override
    public void updateById(String id, Map<String, Object> map) {
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(id));
        Update update = new Update();
        Set<String> keySet = map.keySet();
        for (String key : keySet) {
            update.set(key, map.get(key));
        }
        mongoTemplate.updateFirst(query, update, "comment");
    }

    @Override
    public void delete(String id) {
        commentRepository.deleteById(id);
    }

    @Override
    public List<Comment> findByArticleId(String articleId) {
        return commentRepository.findByArticleId(articleId);
    }

    @Override
    public boolean thumbup(String commentId, String userId) {
        //定义mongodb查询对象
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(commentId));
        //定义mongodb更新对象
        Update update = new Update();
        //从redis获取该用户是否点过赞, flag != null:点赞过, flag == null:没点过
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        //定义评论点赞key:包含用户id与被点赞的评论id
        String key = "thumbup_comment_" + userId + "_" + commentId;
        String flag = redisTemplate.opsForValue().get(key);
        if (flag == null) {
            //没点过赞,更新thumbUp字段 +1
            update.inc("thumbup", 1);
            mongoTemplate.updateFirst(query, update, "comment");
            //并把点赞状态保存入redis
            redisTemplate.opsForValue().set(key, "1");
            return true;
        } else {
            //flag != null,该评论点赞数-1,并删除该用户已点赞状态
            update.inc("thumbup", -1);
            mongoTemplate.updateFirst(query, update, "comment");
            redisTemplate.delete(key);
            return false;
        }
    }


}
